package com.oa.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.joneying.common.annotation.CommonService;
import com.joneying.common.config.SecurityConfig;
import com.joneying.common.redis.RedisManager;
import com.joneying.common.web.response.MessageConstant;
import com.joneying.common.web.response.Resp;
import com.oa.core.PageResult;
import com.oa.core.constant.AdminSetting;
import com.oa.core.exception.BusinessException;
import com.oa.core.exception.DataIsEmptyException;
import com.oa.core.utils.DateUtil;
import com.oa.core.utils.ExcelUtil;
import com.oa.core.utils.MD5Util;
import com.oa.core.utils.ValidateCodeUtil;
import com.oa.pm.entity.Organization;
import com.oa.pm.service.IOrganizationService;
import com.oa.system.dto.MailListDTO;
import com.oa.system.dto.UserAddDTO;
import com.oa.system.dto.UserListDTO;
import com.oa.system.entity.Permission;
import com.oa.system.entity.Post;
import com.oa.system.entity.PostPermission;
import com.oa.system.entity.User;
import com.oa.system.mapper.UserMapper;
import com.oa.system.service.IPermissionService;
import com.oa.system.service.IPostPermissionService;
import com.oa.system.service.IPostService;
import com.oa.system.service.IUserService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.oa.system.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.plugins.Page;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author syb123
 * @since 2019-01-29
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final UserMapper userMapper;
    private final IOrganizationService organizationService;

    @Autowired
    public UserServiceImpl(UserMapper userMapper, IOrganizationService organizationService) {
        this.userMapper = userMapper;
        this.organizationService = organizationService;
    }

    @Autowired
    private RedisManager redisManager;

    @Autowired
    private IPermissionService permissionService;

    @Autowired
    private IPostService postService;

    @Autowired
    private SecurityConfig securityConfig;

    @Autowired
    private IPostPermissionService postPermissionService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Resp<UserVO> login(String ticket) throws IOException {
        Date date = new Date();
        Resp resp = new Resp();

        URL url = new URL(securityConfig.getLoginPage());
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("POST");
        httpConn.setDoOutput(true);
        httpConn.setDoInput(true);
        httpConn.setUseCaches(false);

        String param = "ticket="+ticket+"&action=auth";
        DataOutputStream dos = new DataOutputStream(httpConn.getOutputStream());
        dos.writeBytes(param);
        dos.flush();
        dos.close();

        BufferedReader br = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), "utf-8"));
        String result = br.readLine();

        JSONObject jsonObject = JSONObject.parseObject(result);
        String code = jsonObject.getString("code");
        String id = jsonObject.getString("data");
        String msg = jsonObject.getString("message");

        if(!MessageConstant.SUCCESS.equals(code)){
            return resp.error(MessageConstant.SESSION_EXPIRE, msg);
        }

        User user = userMapper.selectById(id);
        if(user == null){
            user = new User();
            user.setId(id);

            Organization organization = organizationService.selectById(AdminSetting.DEPARTMENT_ID);
            if(organization == null){
                organization = new Organization();
                organization.setId(AdminSetting.DEPARTMENT_ID);
                organization.setCreateId(id);
                organization.setPId(AdminSetting.COMPANY_ID);
                organization.setCreateTime(date);
                organization.setSort(organizationService.selectCount(new EntityWrapper().eq("is_deleted", 2)) + 1);
                organization.setOrganizationName("未分配部门");
                organization.setOrganizationLeader(id);
                organizationService.insert(organization);
            }

            user.setDepartmentId(AdminSetting.DEPARTMENT_ID);
            user.setCompanyId(AdminSetting.COMPANY_ID);
            if(id.equals(AdminSetting.ID)){
                user.setName("admin");
                user.setPostId(AdminSetting.POST_ID);
                Post post = postService.selectById(AdminSetting.POST_ID);
                if(post == null){
                    post = new Post();
                    post.setId(AdminSetting.POST_ID);
                    post.setCreateTime(date);
                    post.setPostName("最高权限");
                    List<PostPermission> postPermissions = new ArrayList<>();
                    List<Permission> permissions = permissionService.selectList(new EntityWrapper<>());
                    permissions.forEach(d -> {
                        PostPermission postPermission = new PostPermission();
                        postPermission.setPermissionId(d.getId());
                        postPermission.setPostId(AdminSetting.POST_ID);
                        postPermissions.add(postPermission);
                    });
                    postService.insert(post);
                    postPermissionService.insertBatch(postPermissions);
                }
            }else{
                user.setName("simm新用户");
            }
            user.setCreateTime(date);
            user.setAuthorizationStatus(1);
            user.setUsername(ValidateCodeUtil.getIntRandom(8));
            user.setPassword(ValidateCodeUtil.getStringRandom(6));
            userMapper.insert(user);
        }

        List<PermissionVO> permissionList = new ArrayList<>();
        if(user.getPostId() != null){
            permissionList = permissionService.findPermissionList(user.getPostId());
        }

        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        userVO.setPermissionVOS(permissionList);
        userVO.setAdmin(true);

        redisManager.set(ticket, userVO, 60 * 30);

        Map<String, Object> res = new HashMap<>();
        res.put("username", userVO.getUsername());
        res.put("name", userVO.getName());
        res.put("jobNo", userVO.getJobNo());
        if(user.getPostId() != null)
            res.put("postName", postService.selectById(user.getPostId()).getPostName() == null?"最高权限":postService.selectById(user.getPostId()).getPostName());
        if(user.getCompanyId() != null)
            res.put("departmentName", organizationService.selectById(user.getDepartmentId()).getOrganizationName() == null?"最高权限":organizationService.selectById(user.getDepartmentId()).getOrganizationName());
        res.put("createTime", userVO.getCreateTime());
        res.put("permissionList", userVO.getPermissionVOS());
        return resp.success(res);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Resp<UserVO> wxlogin(String ticket) {
        Resp resp = new Resp();

        User user = selectOne(new EntityWrapper<User>().eq("wechat_id", redisManager.get(ticket).toString()));

        List<PermissionVO> permissionList = new ArrayList<>();
        if(user.getPostId() != null){
            permissionList = permissionService.findPermissionList(user.getPostId());
        }

        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        userVO.setPermissionVOS(permissionList);
        userVO.setAdmin(true);

        redisManager.set(ticket, userVO, 60 * 30);

        Map<String, Object> res = new HashMap<>();
        res.put("username", userVO.getUsername());
        res.put("name", userVO.getName());
        res.put("jobNo", userVO.getJobNo());
        if(user.getPostId() != null)
            res.put("postName", postService.selectById(user.getPostId()).getPostName() == null?"最高权限":postService.selectById(user.getPostId()).getPostName());
        if(user.getCompanyId() != null)
            res.put("departmentName", organizationService.selectById(user.getDepartmentId()).getOrganizationName() == null?"最高权限":organizationService.selectById(user.getDepartmentId()).getOrganizationName());
        res.put("createTime", userVO.getCreateTime());
        res.put("permissionList", userVO.getPermissionVOS());
        return resp.success(res);
    }


    /**
     * 添加用户
     *
     * @param userAddDTO
     * @return
     */
    @Override
    @CommonService
    @Transactional
    public Resp addUser(UserAddDTO userAddDTO) throws BusinessException {
        User user = new User();
        BeanUtils.copyProperties(userAddDTO, user);

        String md5Password = MD5Util.md5Password(user.getPassword());
        user.setPassword(md5Password);
        System.out.println("密码:" + md5Password);

        String companyId = organizationService.findCompanyIdByDepartmentId(user.getDepartmentId());
        user.setCompanyId(companyId);

        user.setCreateTime(new Date());

        try {
            insert(user);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("添加用户失败!");
        }
        return new Resp<String>().success("添加用户成功!");
    }

    /**
     * 根据条件查询用户列表
     *
     * @param
     * @param
     * @param userName
     * @param name
     * @param createTime
     * @param organizationName
     * @return
     */
    @Override
    @CommonService
    public PageResult<UserVO> findUserListByCondition(Integer pageNum, Integer pageSize, String userName, String name, String createTime, String organizationName) throws DataIsEmptyException {

        if (pageNum == null) {
            List<UserVO> userVOList = userMapper.findUserListByCondition(userName, name, createTime, organizationName);
            if (CollUtil.isEmpty(userVOList)) {
                throw new DataIsEmptyException();
            }
            return new PageResult<>(userVOList);

        } else {
            Page<Post> page = new Page<>(pageNum, pageSize);
            List<UserVO> userVOList = userMapper.findUserListByCondition(page, userName, name, createTime, organizationName);
            if (CollUtil.isEmpty(userVOList)) {
                throw new DataIsEmptyException();
            }
            return new PageResult<>(userVOList);
        }
    }

    /**
     * 根据id查询用户详情
     *
     * @param id
     * @return
     */
    @Override
    @CommonService
    public Resp findUserDetailsById(String id) throws DataIsEmptyException {
        UserDetailsVO userDetailsVO = userMapper.findUserDetailsById(id);
        if (StringUtils.isEmpty(userDetailsVO)) {
            throw new DataIsEmptyException();
        }
        return new Resp<UserDetailsVO>().success(userDetailsVO);
    }

    /**
     * 根据id修改用户
     *
     * @param userUpdateVO
     * @return
     */
    @Override
    @CommonService
    @Transactional
    public Resp updateUserDetailsById(UserUpdateVO userUpdateVO) throws BusinessException {

        User user = new User();
        BeanUtils.copyProperties(userUpdateVO, user);

        //当密码不为空时,修改密码
        if (!StringUtils.isEmpty(user.getPassword())) {
            String md5Password = MD5Util.md5Password(user.getPassword());
            user.setPassword(md5Password);
        }

        try {
            updateById(user);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("修改用户失败!");
        }
        return new Resp<String>().success("修改用户成功!");
    }

    /**
     * 根据ids启用或者禁用用户
     *
     * @param ids
     * @param type
     * @return
     */
    @Override
    @CommonService
    @Transactional
    public Resp EnableOrDisableUserById(String ids, String type) throws BusinessException {

        List<User> userList = new ArrayList<>();
        //类型[1-启用 2-禁用]
        if ("1".equals(type)) {
            for (String id : ids.split(",")) {
                User user = selectById(id);
                user.setAuthorizationStatus(1);
                userList.add(user);
            }
        }
        if ("2".equals(type)) {
            for (String id : ids.split(",")) {
                User user = selectById(id);
                user.setAuthorizationStatus(2);
                userList.add(user);
            }
        }
        try {
            updateBatchById(userList);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("操作失败!");
        }

        return new Resp<String>().success("操作成功!");
    }

    /**
     * 根据id删除用户
     *
     * @param id
     * @return
     */
    @Override
    @CommonService
    @Transactional
    public Resp deleteUserById(String id) throws DataIsEmptyException, BusinessException {
        User user = selectById(id);
        if (StringUtils.isEmpty(user)) {
            throw new DataIsEmptyException();
        }

        user.setIsDeleted(1);

        try {
//            updateById(user);
            deleteById(id);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("删除用户失败!");
        }
        return new Resp<String>().success("删除用户成功!");
    }

    @Override
    public PageResult<UserListVO> findUserList(UserListDTO userListDTO) {
        Page<UserListVO> page = userListDTO.getPage();
        if(page == null){
            return new PageResult<>(userMapper.findUserList(new Page(), userListDTO));
        }
        return new PageResult<>(userMapper.findUserList(page, userListDTO), page.getPages());
    }

    @Override
    public PageResult<MailListVO> findMailList(MailListDTO<MailListVO> mailListDTO) {
        Page<MailListVO> page = mailListDTO.getPage();
        List<MailListVO> mailListVOS = userMapper.findMailList(page, mailListDTO);
        return new PageResult<>(mailListVOS, page.getPages());
    }

    @Override
    public List<UserByOrganizationVO> findUserByOrganization(String departmentId, String companyId) {
        return userMapper.findUserByOrganization(departmentId, companyId);
    }

    @Override
    public Integer findRanking(String id, String createTimeYear) {
        return userMapper.findRanking(id, createTimeYear);
    }


    @Override
    public void exportMailList(HttpServletResponse response) {
        List<MailListVO> mailListVOS = userMapper.findMailList(new Page(), new MailListDTO());

        String[] rows = {"姓名", "部门名称", "联系电话", "邮箱"};
        try {
            ExcelUtil.downloadExcel("通讯录" + DateUtil.getDayMonth(), rows, mailListVOS, "通讯录" + DateUtil.getDayMonth()+".xls", response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
